// --------------------------------------------------------------------------------------------------------------------
// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
// --------------------------------------------------------------------------------------------------------------------

namespace WP7Contrib.View.Controls.DateTimePicker
{
    using System;
    using System.Threading;
    using System.Windows.Controls;

    using Microsoft.Phone.Controls.Primitives;

    public abstract class DataSource : ILoopingSelectorDataSource
    {
        // Fields
        private DateTimeWrapper _selectedItem;
        private EventHandler<SelectionChangedEventArgs> SelectionChanged;
        public event EventHandler<SelectionChangedEventArgs> AltSelectionChanged;
       
        // Events
        /// <summary>
        /// xxx ddd ddddddd
        /// </summary>
        event EventHandler<SelectionChangedEventArgs> ILoopingSelectorDataSource.SelectionChanged
        {
            add
            {
                EventHandler<SelectionChangedEventArgs> handler2;
                EventHandler<SelectionChangedEventArgs> selectionChanged = this.SelectionChanged;
                do
                {
                    handler2 = selectionChanged;
                    EventHandler<SelectionChangedEventArgs> handler3 = (EventHandler<SelectionChangedEventArgs>)Delegate.Combine(handler2, value);
                    selectionChanged = Interlocked.CompareExchange<EventHandler<SelectionChangedEventArgs>>(ref this.SelectionChanged, handler3, handler2);
                }
                while (selectionChanged != handler2);
            }
            remove
            {
                EventHandler<SelectionChangedEventArgs> handler2;
                EventHandler<SelectionChangedEventArgs> selectionChanged = this.SelectionChanged;
                do
                {
                    handler2 = selectionChanged;
                    EventHandler<SelectionChangedEventArgs> handler3 = (EventHandler<SelectionChangedEventArgs>)Delegate.Remove(handler2, value);
                    selectionChanged = Interlocked.CompareExchange<EventHandler<SelectionChangedEventArgs>>(ref this.SelectionChanged, handler3, handler2);
                }
                while (selectionChanged != handler2);
            }
        }



        /// <summary>
        /// Get the next datum, relative to an existing datum.
        /// </summary>
        /// <param name="relativeTo">The datum the return value will be relative to.</param>
        /// <returns>The next datum.</returns>
        public object GetNext(object relativeTo)
        {
            DateTime? nullable = this.GetRelativeTo(((DateTimeWrapper)relativeTo).DateTime, 1);
            return (nullable.HasValue ? new DateTimeWrapper(nullable.Value) : null);
        }

        /// <summary>
        /// Get the previous datum, relative to an existing datum.
        /// </summary>
        /// <param name="relativeTo">The datum the return value will be relative to.</param>
        /// <returns>The previous datum.</returns>
        public object GetPrevious(object relativeTo)
        {
            DateTime? nullable = this.GetRelativeTo(((DateTimeWrapper)relativeTo).DateTime, -1);
            return (nullable.HasValue ? new DateTimeWrapper(nullable.Value) : null);
        }

        /// <summary>
        /// Gets the relative to.
        /// </summary>
        /// <param name="relativeDate">The relative date.</param>
        /// <param name="delta">The delta.</param>
        /// <returns></returns>
        protected abstract DateTime? GetRelativeTo(DateTime relativeDate, int delta);

        // Properties
        /// <summary>
        /// The selected item. Should never be null.
        /// </summary>
        /// <value></value>
        public object SelectedItem
        {
            get
            {
                return this._selectedItem;
            }
            set
            {
                if (value != this._selectedItem)
                {
                    DateTimeWrapper wrapper = (DateTimeWrapper)value;
                    if (((wrapper == null) || (this._selectedItem == null)) || (wrapper.DateTime != this._selectedItem.DateTime))
                    {
                        object obj2 = this._selectedItem;
                        this._selectedItem = wrapper;
                        EventHandler<SelectionChangedEventArgs> selectionChanged = this.SelectionChanged;
                        //if (null != selectionChanged)
                        //{
                        //   // Can't use the original line because it tries to cast this as its own DataSource (which is an internal class)
                        //   // selectionChanged(this, new SelectionChangedEventArgs(new object[] { obj2 }, new object[] { this._selectedItem }));

                        //}

                        if (this.AltSelectionChanged != null)
                        {
                            this.AltSelectionChanged(this, new SelectionChangedEventArgs(new object[] { obj2 }, new object[] { this._selectedItem }));
                        }
                    }
                }
            }
        }
    }
}